<template>
  <view v-if="!isLoading" class="container" :style="appThemeStyle">
    <view class="cell-group">
      <view class="cell-item">
        <view class="label">收货人：</view>
        <view class="value">{{ order.clientName }}</view>
      </view>
      <view class="cell-item">
        <view class="label">手机号：</view>
        <view class="value">{{ order.clientPhone }}</view>
      </view>
      <view class="cell-item">
        <view class="label">地&nbsp;&nbsp;&nbsp;址：</view>
        <view class="value address">{{ order.clientAddress || '无' }}</view>
      </view>
    </view>
    <view class="cell-group">
      <view class="cell-item flex-x-between">
        <view class="label">发货类型</view>
        <view class="value dis-flex flex-y-center">
          <u-radio-group v-model="logisticsType">
            <u-radio
              v-for="(item, index) in logisticsTypeList"
              :key="index"
              :name="item.name"
              :disabled="item.disabled"
            >
              {{ item.name }}
            </u-radio>
          </u-radio-group>
        </view>
      </view>
      <view v-if="logisticsType === LOGISTICS_TYPE.ALL">
        <view class="cell-item flex-x-between" @click="showLogisticsPopup = true">
          <view class="label">快递公司</view>
          <view class="value">
            <text :class="['gray', { active: form.express }]">{{ form.express || '请选择或搜索快递公司' }}</text>
            <text class="iconfont icon-arrow-right"></text>
          </view>
        </view>
        <view class="cell-item flex-x-between">
          <view class="label t-l">运单号</view>
          <view class="value">
            <u-input
              v-model="form.courierNumber"
              input-align="right"
              placeholder="请输入运单号"
              :custom-style="{
                marginRight: '16rpx'
              }"
            />
            <text class="iconfont icon-scan" @click="handleScan('form')">&#xe6af;</text>
          </view>
        </view>
      </view>
      <view class="parcel" v-if="logisticsType === LOGISTICS_TYPE.MORE">
        <view class="parcel-item" v-for="(item, index) in alreadyList" :key="index">
          <view class="title">
            <text>包裹{{ index + 1 }}</text>
          </view>
          <view class="cell-item flex-x-between">
            <view class="label">发货商品</view>
            <view class="value" @click="showAlreadyGoods(index)">
              <text class="blue">{{ goodsCount(item.goodsList) }}</text>
              <text class="iconfont icon-arrow-right"></text>
            </view>
          </view>
          <view class="cell-item flex-x-between">
            <view class="label">快递公司</view>
            <view class="value">
              <text class="gray">{{ item.express }}</text>
            </view>
          </view>
          <view class="cell-item flex-x-between">
            <view class="label t-l">运单号</view>
            <view class="value">
              <u-input
                v-model="item.courierNumber"
                input-align="right"
                placeholder="请输入运单号"
                :custom-style="{
                  marginRight: '16rpx',
                  color: '#CCCCCC'
                }"
                :disabled="true"
              />
              <text class="iconfont icon-scan gray">&#xe6af;</text>
            </view>
          </view>
        </view>
        <view class="parcel-item" v-for="(item, index) in expressList" :key="index">
          <view class="title">
            <text>包裹{{ alreadyList.length + index + 1 }}</text>
            <text class="iconfont icon-delete" v-if="index !== 0" @click="handleRemove(index)"></text>
          </view>
          <view class="cell-item flex-x-between">
            <view class="label">发货商品</view>
            <view class="value" @click="showGoods(index)">
              <text :class="['gray', { blue: item.goodsList }]">{{ goodsCount(item.goodsList) }}</text>
              <text class="iconfont icon-arrow-right"></text>
            </view>
          </view>
          <view class="cell-item flex-x-between" @click="showLogistics(index)">
            <view class="label">快递公司</view>
            <view class="value">
              <text :class="['gray', { active: item.express }]">{{ item.express || '请选择或搜索快递公司' }}</text>
              <text class="iconfont icon-arrow-right"></text>
            </view>
          </view>
          <view class="cell-item flex-x-between">
            <view class="label t-l">运单号</view>
            <view class="value">
              <u-input
                v-model="item.courierNumber"
                input-align="right"
                placeholder="请输入运单号"
                :custom-style="{
                  marginRight: '16rpx'
                }"
              />
              <text class="iconfont icon-scan" @click="handleScan(item)">&#xe6af;</text>
            </view>
          </view>
        </view>
        <view class="add-parcel" @click="addParcel">添加包裹</view>
      </view>
    </view>
    <!-- 底部操作按钮 -->
    <view class="footer-fixed">
      <view class="btn-wrapper">
        <u-button :custom-style="{ width: '330rpx'}" @click="cancel">取消</u-button>
        <u-button :custom-style="{ width: '330rpx'}" type="primary" @click="submit">确认</u-button>
      </view>
    </view>
    <!-- 物流公司 -->
    <u-popup
      v-model="showLogisticsPopup"
      mode="bottom"
      border-radius="20"
      :safe-area-inset-bottom="true"
      :closeable="true"
      :mask-custom-style="{ background: 'rgba(0, 0, 0, 0.7)' }"
    >
      <view class="popup-content">
        <view class="page-title">选择快递公司</view>
        <u-search
          shape="square"
          placeholder="请输入物流公司名称"
          v-model="searchValue"
          :action-style="{
            color: appTheme.mainBg
          }"
          :show-action="true"
          action-text="取消"
          :animation="true"
          @search="onSearch"
          @custom="onClear"
          @clear="onSearch"
        ></u-search>
        <scroll-view class="content-scroll" :scroll-y="true">
          <view class="list">
            <view
              class="item"
              v-for="(item, index) in logisticsChannels"
              :key="index"
              :class="{active: index === selectedIndex}"
              @click="selectItem(item, index)"
            >
              <text class="name">{{ item.logisticsName }}</text>
              <text class="iconfont selected" v-if="index === selectedIndex">&#xe6ad;</text>
            </view>
          </view>
        </scroll-view>
      </view>
    </u-popup>
    <!-- 商品弹窗 -->
    <u-popup
      v-model="showGoodsPopup"
      mode="bottom"
      border-radius="20"
      :safe-area-inset-bottom="true"
      :closeable="true"
      :mask-custom-style="{ background: 'rgba(0, 0, 0, 0.7)'}"
    >
      <view class="popup-content goods-popup">
        <view class="page-title">商品信息</view>
        <scroll-view class="content-scroll" :scroll-y="true">
          <view class="goods-list">
            <view class="goods-item" v-for="(item, index) in goodsList" :key="index">
              <view class="item-flex">
                <view class="item-radio">
                  <view
                    @click="handleCheckItem(item.orderGoodsId)"
                    v-if="(item.quantity - item.refundQuantity - item.sentQuantity) !== 0"
                  >
                    <u-checkbox
                      :modelValue="inArray(item.orderGoodsId, checkedIds)"
                      shape="circle"
                      :activeColor="appTheme.mainBg"
                    />
                  </view>
                </view>
                <view class="image-wrap">
                  <image :src="item.primaryPicUrl" />
                </view>
                <view class="good-info">
                  <view class="title-wrap twoline-hide">{{ item.goodsName }}</view>
                  <view class="describe">编码：{{ item.skuCode }}</view>
                  <view class="describe">条码：{{ item.barcode }}</view>
                  <view class="describe">
                    <text>重量：{{ item.weight || 0 }}g</text>
                    <text>x {{ (item.quantity - item.refundQuantity - item.sentQuantity) || 0 }}</text>
                  </view>
                </view>
              </view>
              <view class="stepper">
                <view class="tag" v-if="item.sentQuantity">已发货{{item.sentQuantity}}件</view>
                <text class="text">发货数量：</text>
                <u-number-box
                  :modelValue="item.selectedQuantity"
                  :max="(item.quantity - item.refundQuantity - item.sentQuantity) || 0"
                  :step="1"
                  @change="onChangeStepper($event, item)"
                />
              </view>
            </view>
          </view>
        </scroll-view>
        <view class="footer-fixed">
          <view class="btn-wrapper">
            <u-button :custom-style="{ width: '330rpx'}" @click="cancelGoods">取消</u-button>
            <u-button :custom-style="{ width: '330rpx'}" type="primary" @click="confirmGoods">确认</u-button>
          </view>
        </view>
      </view>
    </u-popup>
    <!-- 已发货商品弹窗 -->
    <u-popup
      v-model="alreadyGoodsPopup"
      mode="bottom"
      border-radius="20"
      :safe-area-inset-bottom="true"
      :closeable="true"
      :mask-custom-style="{ background: 'rgba(0, 0, 0, 0.7)'}"
    >
      <view class="popup-content goods-popup">
        <view class="page-title">商品信息</view>
        <scroll-view class="content-scroll" :scroll-y="true">
          <view class="goods-list">
            <view class="goods-item" v-for="(item, index) in alreadyGoods" :key="index">
              <view class="item-flex">
                <view class="image-wrap">
                  <image :src="item.primaryPicUrl" />
                </view>
                <view class="good-info">
                  <view class="title-wrap twoline-hide">{{ item.goodsName }}</view>
                  <view class="describe">编码：{{ item.skuCode }}</view>
                  <view class="describe">条码：{{ item.barcode }}</view>
                  <view class="describe">
                    <text>重量：{{ item.weight || 0 }}g</text>
                    <text>x {{ item.quantity || 0 }}</text>
                  </view>
                </view>
              </view>
            </view>
          </view>
        </scroll-view>
      </view>
    </u-popup>
    <!-- 未全部发货提示 -->
    <u-modal
      v-model="showModal"
      show-confirm-button
      show-cancel-button
      :show-title="false"
      content="订单未全部发货用户可能无法收到提醒，是否继续发货？"
      @confirm="confirmModal"
    ></u-modal>
  </view>
</template>
<script>
import * as OrderApi from '@/api/order/order'
import * as SettingApi from '@/api/setting'
import { inArray, cloneObj } from '@/utils/util'

let logisticsChannels = []

const LOGISTICS_TYPE = {
  ALL: '整单发货',
  MORE: '多物流发货'
}

export default {
  name: "index",
  data() {
    return {
      LOGISTICS_TYPE,
      inArray,
      form: {
        express: '',
        courierNumber: ''
      },
      // 加载中
      isLoading: true,
      orderId: null,
      order: {},
      logisticsTypeList: [
        { name: LOGISTICS_TYPE.ALL, disabled: false },
        { name: LOGISTICS_TYPE.MORE, disabled: false }
      ],
      logisticsType: LOGISTICS_TYPE.ALL,
      showLogisticsPopup: false,
      selectedIndex: -1,
      searchValue: '',
      goodsList: [],
      showGoodsPopup: false,
      logisticsChannels: [],
      expressList: [{
        express: '',
        courierNumber: ''
      }],
      currentIndex: -1,
      checkedIds: [],
      alreadyList: [],
      alreadyGoodsPopup: false,
      alreadyGoods: [],
      showModal: false
    }
  },
  computed: {
    goodsCount() {
      return (val) => {
        return val?.length ? `共${val.reduce((pre, cur) => pre + cur.quantity, 0)}件` : '选择商品'
      }
    }
  },
  async onLoad({ orderId }) {
    this.orderId = orderId
    await this.getLogisticsChannels()
    await this.getLogisticsDetail()
  },
  methods: {
    async getLogisticsChannels() {
      const { data } = await SettingApi.logisticsChannels()
      if (data) this.logisticsChannels = logisticsChannels = data
    },
    async getLogisticsDetail() {
      this.isLoading = true
      const { data } = await OrderApi.getLogisticsDetail(this.orderId, { load: false })
      if (data) {
        const { expressList } = data
        this.order = data
        this.isLoading = false
        if (expressList.length) {
          const tmp = this.logisticsTypeList.find(item => item.name === LOGISTICS_TYPE.ALL)
          tmp.disabled = true
          this.logisticsType = LOGISTICS_TYPE.MORE
          this.alreadyList = expressList
        }
      }
    },
    onSearch() {
      this.logisticsChannels = logisticsChannels
      if (this.searchValue) {
        this.logisticsChannels = this.logisticsChannels.filter(item => item?.logisticsName.includes(this.searchValue))
      }
    },
    onClear() {
      this.searchValue = ''
      this.onSearch()
    },
    addParcel() {
      this.expressList.push({
        express: '',
        courierNumber: ''
      })
    },
    handleRemove(index) {
      this.expressList.splice(index, 1)
    },
    showGoods(index) {
      this.checkedIds = []
      const goodsList = cloneObj(this.order.goodsList)
      // 判断是否是回显
      const currentGoods = this.expressList[index].goodsList
      // 回显选中状态的checkbox
      if (currentGoods) this.checkedIds = currentGoods.map(item => item.orderGoodsId)
      // 多物流发货存储的商品信息
      const goodsChild = this.expressList.map(item => item.goodsList).filter(Boolean).flat()
      // 如果map中已经有这个id，则累加quantity, 否则，设置quantity为当前item的quantity
      const uniqueChild = Array.from(
        goodsChild.reduce((map, item) => {
          map.set(item.orderGoodsId, (map.get(item.orderGoodsId) || 0) + item.quantity)
          return map
        }, new Map()).entries(),
        ([orderGoodsId, quantity]) => ({ orderGoodsId, quantity })
      )
      // 更新 goodsList 中的商品数量
      goodsList.forEach(item => {
        // 初始化选中数量为0
        item.selectedQuantity = 0
        const childGoods = uniqueChild.find(good => good.orderGoodsId === item.orderGoodsId)
        if (childGoods) {
          // 如果当前商品在 goodsChild 中存在
          const totalSelected = goodsChild.reduce((acc, good) => {
            if (good.orderGoodsId === item.orderGoodsId) {
              acc += good.quantity // 累加所有相同 id 的商品数量
            }
            return acc
          }, 0)
          // 更新商品剩余数量
          item.quantity -= totalSelected
          // 如果是回显，且当前包裹的商品列表中有这个商品，则可能需要特殊处理（这里假设 currentGoods 已经是对应包裹的商品列表）
          if (currentGoods) {
            const currentGoodsForThisPackage = currentGoods.find(good => good.orderGoodsId === item.orderGoodsId)
            if (currentGoodsForThisPackage) {
              // 当前包裹商品数量回显
              item.selectedQuantity = currentGoodsForThisPackage.quantity
              // 因为上一步循环减去了所有选中的数量，这里回显时需要加上当前回显的选中数量，这样 goodsList 循环下的quantity就是只减去了非当前项的值
              // （比方说非当前项有一个1，当前项选了2个，循环减去的是10-1-2=7，这里在加上当前项，就是7+2=9，那么总数量还有9个可选）
              item.quantity += item.selectedQuantity
            }
          }
        }
      });
      this.goodsList = goodsList
      this.currentIndex = index
      this.showGoodsPopup = true
    },
    // 已发货商品回显
    showAlreadyGoods(index) {
      const goodsList = cloneObj(this.order.goodsList)
      const alreadyGoods = this.alreadyList[index].goodsList
      const mergedArray = alreadyGoods.map(item => {
        const tmp = goodsList.find(val => item.orderGoodsId === val.orderGoodsId)
        if (tmp) {
          return { ...tmp, ...item }
        }
        return item
      })
      this.alreadyGoods = mergedArray
      this.alreadyGoodsPopup = true
    },
    handleScan(item) {
      uni.scanCode({
        success: res => {
          const { result } = res
          if (item === 'form') {
            this.form.courierNumber = result
          } else {
            item.courierNumber = result
          }
        },
        fail: () => {
          this.$toast('未识别到该运单号')
        }
      })
    },
    onChangeStepper({ value }, item) {
      item.selectedQuantity = value
    },
    showLogistics(index) {
      this.currentIndex = index
      this.selectedIndex = -1
      this.showLogisticsPopup = true
    },
    selectItem(item, index) {
      this.selectedIndex = index
      if (this.logisticsType === LOGISTICS_TYPE.ALL) this.form.express = item.logisticsName
      else this.expressList[this.currentIndex].express = item.logisticsName
      this.showLogisticsPopup = false
    },
    // 选中商品
    handleCheckItem(orderGoodsId) {
      const { checkedIds } = this
      const index = checkedIds.findIndex(id => id === orderGoodsId)
      index < 0 ? checkedIds.push(orderGoodsId) : checkedIds.splice(index, 1)
    },
    confirmGoods() {
      if (!this.checkedIds.length) return this.$toast('请选中商品！')
      const goodsList = this.goodsList.filter(item => this.checkedIds.includes(item.orderGoodsId)).map(val => {
        return {
          orderGoodsId: val.orderGoodsId,
          quantity: val.selectedQuantity
        }
      })
      const isSome = goodsList.some(item => !item.quantity)
      if (isSome) return this.$toast('选中的商品数量不能为0！')
      this.expressList[this.currentIndex].goodsList = goodsList
      this.showGoodsPopup = false
    },
    cancelGoods() {
      this.showGoodsPopup = false
      this.checkedIds = []
    },
    submit() {
      const { goodsList } = this.order
      if (this.logisticsType === LOGISTICS_TYPE.ALL) {
        if (!this.form.express) return this.$toast('请选择物流公司！')
        else if (!this.form.courierNumber) return this.$toast('请输入运单号！')
        this.form.goodsList = goodsList.map(val => {
          return {
            orderGoodsId: val.orderGoodsId,
            quantity: val.quantity,
          }
        })
      } else {
        for(let i = 0; i < this.expressList.length; i++) {
          const item = this.expressList[i]
          if (!item.goodsList) return this.$toast('请选择商品！')
          else if (!item.express) return this.$toast('请选择物流公司！')
          else if (!item.courierNumber) return this.$toast('请输入运单号！')
        }
        const goodsTotal = goodsList.reduce((pre, cur) => pre + (cur.quantity - cur.refundQuantity - cur.sentQuantity), 0)
        const totalQuantity = this.expressList.reduce((acc, currArray) => {
          return acc + currArray.goodsList?.reduce((innerAcc, item) => {
            return innerAcc + item.quantity
          }, 0)
        }, 0)
        if (goodsTotal !== totalQuantity) return this.showModal = true
      }
      this.saveLogistics()
    },
    saveLogistics() {
      const params = {
        orderId: this.orderId,
        expressList: this.logisticsType === LOGISTICS_TYPE.ALL ? [this.form] : this.expressList
      }
      OrderApi.logisticsDelivery(params).then(res => {
        if (res.data) {
          this.$toast('操作完成')
          setTimeout(() => {
            uni.navigateBack()
          }, 1500)
          uni.$emit('syncRefresh', true)
        }
      }).catch(() => {})
    },
    confirmModal() {
      this.saveLogistics()
    },
    cancel() {
      uni.navigateBack()
    }
  }
}
</script>

<style scoped lang="scss">
.container {
  padding: 24rpx;
  // 设置ios刘海屏底部横线安全区域
  padding-bottom: calc(constant(safe-area-inset-bottom) + 140rpx);
  padding-bottom: calc(env(safe-area-inset-bottom) + 140rpx);

  .cell-group {
    padding: 24rpx;
    background: #fff;
    border-radius: 16rpx;
    margin-top: 16rpx;

    .cell-item {
      display: flex;
      line-height: 90rpx;

      .label {
        width: 120rpx;
        text-align: center;
        color: #666;

        &.t-l {
          text-align: left;
        }
      }

      .value {
        display: flex;
        align-items: center;

        &.address {
          width: calc(100% - 120rpx);
        }

        .gray {
          color: #CCCCCC;
          margin-right: 16rpx;

          &.active {
            color: #333;
          }
        }

        .blue {
          color: #2D71FD;
        }

        .icon-arrow-right {
          font-size: 40rpx;
          color: #666;
        }

        .icon-scan {
          font-size: 30rpx;
        }
      }
    }
  }

  .parcel {

    .parcel-item {
      padding: 0 24rpx;
      background: #F5F6F9;
      border-radius: 16rpx;
      margin-bottom: 20rpx;

      .title {
        padding: 24rpx 0 10rpx;
        font-size: 28rpx;
        color: #000000;
        display: flex;
        justify-content: space-between;
        align-items: center;

        .iconfont {
          font-size: 30rpx;
        }
      }
    }

    .add-parcel {
      color: $main-bg;
      padding: 20rpx 0 0 10rpx;
    }
  }

  // 底部操作栏
  .footer-fixed {
    position: fixed;
    bottom: var(--window-bottom);
    left: 0;
    right: 0;
    z-index: 11;
    background: #fff;
    border-top: 2rpx solid #eee;
    // 设置ios刘海屏底部横线安全区域
    padding-bottom: constant(safe-area-inset-bottom);
    padding-bottom: env(safe-area-inset-bottom);

    .btn-wrapper {
      padding: 16rpx 32rpx;
      display: flex;
      align-items: center;
      justify-content: space-between;
    }
  }

  .popup-content {
    padding: 24rpx;

    .page-title {
      text-align: center;
      margin-bottom: 40rpx;
      font-size: 36rpx;
      font-weight: bold;
    }

    .content-scroll {
      min-height: 30vh;
      max-height: 65vh;

      .list {
        margin-top: 24rpx;

        .item {
          margin-bottom: 24rpx;
          display: flex;
          align-items: center;
          justify-content: space-between;
          border-radius: 16rpx;
          border: 1rpx solid var(--eeeeee, #EEE);
          padding: 24rpx;
          font-size: 26rpx;

          &.active {
            border: 1rpx solid #2D71FD;

            .name {
              font-weight: bold;
            }
          }

          .selected {
            color: #2D71FD;
            font-size: 40rpx;
          }
        }
      }
    }
  }

  .goods-popup {
    background: #F3F5FA;
    padding: 24rpx;


    .goods-list {
      // 设置ios刘海屏底部横线安全区域
      padding-bottom: calc(constant(safe-area-inset-bottom) + 100rpx);
      padding-bottom: calc(env(safe-area-inset-bottom) + 100rpx);

      .goods-item {
        padding: 20rpx 16rpx;
        background: #fff;
        border-radius: 16rpx;
        margin-bottom: 16rpx;

        .item-flex {
          display: flex;
          align-items: center;

          .item-radio {
            width: 50rpx;
          }

          .image-wrap {
            width: 128rpx;
            height: 128rpx;
            position: relative;

            image {
              width: 100%;
              height: 100%;
            }
          }

          .good-info {
            flex: 1;
            margin-left: 16rpx;
            position: relative;

            .title-wrap {
              font-size: 28rpx;
              margin-bottom: 10rpx;
            }

            .describe {
              font-size: 24rpx;
              line-height: 42rpx;
              color: #999;
              display: flex;
              align-items: center;
              justify-content: space-between;
            }
          }
        }

        .stepper {
          margin-top: 20rpx;
          display: flex;
          align-items: center;
          justify-content: flex-end;

          .tag {
            padding: 5rpx 10rpx;
            border-radius: 8rpx;
            font-size: 20rpx;
            background: #f0f7ff;
            color: #2D71FD;
          }

          .text {
            margin: 0 16rpx;
            font-size: 24rpx;
            color: #666666;
          }
        }
      }
    }
  }

  ::-webkit-scrollbar {
    width: 0;
    height: 0;
    color: transparent;
  }
}
</style>
